package ch.fusun.baron.property.ui;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import ch.fusun.baron.core.injection.Inject;
import ch.fusun.baron.data.DataListener;
import ch.fusun.baron.data.DataUpdate;
import ch.fusun.baron.map.Tile;
import ch.fusun.baron.map.api.GameMapService;
import ch.fusun.baron.map.ui.gef.editpart.TileChild;
import ch.fusun.baron.map.ui.gef.editpart.TileChildrenProvider;
import ch.fusun.baron.property.api.PropertyService;

/**
 * Provides the borders
 */
public class PropertyTileExtensionProvider implements TileChildrenProvider {

    private PropertyService propertyService;
    @Inject
    private GameMapService mapService;
    private final List<DataListener> listeners = new LinkedList<DataListener>();

    /**
     * Injection constructor
     */
    public PropertyTileExtensionProvider() {
    }

    /**
     * @param service
     *            The injected service
     */
    @Inject
    public void setPropertyService(PropertyService service) {
        this.propertyService = service;
        this.propertyService.addDataListener(this);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Collection<TileChild> getChildren(Tile tile) {
        List<TileChild> list = new LinkedList<TileChild>();
        if (propertyService.isOwned(tile)) {
            int index = calculateIndex(tile);
            if (index > 0) {
                list.add(new PropertyTileChild(index));
            }
        }
        return list;
    }

    private int calculateIndex(Tile tile) {
        Object tileOwnerShip = propertyService.getOwnership(tile);
        int result = 0;

        int x = tile.getX();
        int y = tile.getY();
        int width = mapService.getWidth();
        int height = mapService.getHeight();

        if (!tileOwnerShip.equals(propertyService.getOwnership(mapService
                .getTile(x % width, (y + 1) % height)))) {
            result |= 8;
        }
        if (!tileOwnerShip.equals(propertyService.getOwnership(mapService
                .getTile(x % width, (y - 1 + height) % height)))) {
            result |= 2;
        }
        if (!tileOwnerShip.equals(propertyService.getOwnership(mapService
                .getTile((x + 1) % width, y % height)))) {
            result |= 1;
        }
        if (!tileOwnerShip.equals(propertyService.getOwnership(mapService
                .getTile((x - 1 + width) % width, y % height)))) {
            result |= 4;
        }

        return result;
    }

    @Override
    public void addListener(DataListener listener) {
        this.listeners.add(listener);
    }

    @Override
    public void dataChanged(DataUpdate update) {
        for (DataListener listener : listeners) {
            listener.dataChanged(update);
        }
    }
}
